"""
A simple implementation of connectors using a tk canvas.
"""

from Tkinter import *

class _Canvas(Canvas):
    WIDTH = 640
    HEIGHT = 480
    LEFTX = WIDTH//10
    RIGHTX = 8*WIDTH//10
    DX = WIDTH//10
    DY = HEIGHT//10
    def __init__(self, master):
        Canvas.__init__(self, master, width=self.WIDTH, height=self.HEIGHT)
        master.canvas = self
        self.configure(bg='black')
        self.pack()
        self.reset() # start with a clean sheet
    def reset(self):
        self.sd = []
        self.srcs = set()
        self.dsts = set()
        self.lefty = self.DY
        self.righty = self.DY
    def add_srcdst(self, sd):
        self.sd.append(sd)
        self.srcs.add(sd.src)
        self.dsts.add(sd.dst)
    def left(self, src):
        self.create_rectangle(self.LEFTX, self.lefty,
                              self.LEFTX+self.DX, self.lefty+self.DY,
                              fill='green')
        self.create_text(self.LEFTX+self.DX//2,self.lefty+self.DY//2, text=src, tag='src_%s' % src)
        self.lefty += (3*self.DY//2)
    def right(self,dst):
        self.create_rectangle(self.RIGHTX, self.righty,
                              self.RIGHTX+self.DX, self.righty+self.DY,
                              fill='red')
        self.create_text(self.RIGHTX+self.DX//2,self.righty+self.DY/2, text=dst, tag='dst_%s' % dst)
        self.righty += (3*self.DY//2)
    def join(self, sd):
        start = self.coords('src_%s' % sd.src)
        end = self.coords('dst_%s' % sd.dst)
        self.create_line(*(start + end), fill='yellow', tag='connector')
        self.tag_lower('connector')
    def draw(self):
        self.delete('all')
        self.create_rectangle(5*self.DX, self.DY,
                              9*self.DX, 9*self.DY, fill='gray', tag='connector')
        for s in sorted(self.srcs):
            self.left(s)
        for d in sorted(self.dsts):
            self.right(d)
        for sd in self.sd:
            self.join(sd)
        self.reset() # keep a clean sheet for next time

class _Button(Button):
    def __init__(self, master, *a, **k):
        Button.__init__(self, master, *a, **k)
        self.pack()

class App(Tk):
    def __init__(self):
        self.test_data_index = 0
        Tk.__init__(self)
        _Canvas(self)
        _Button(self, text='Next',command=self.next)
        self.next()
        self.mainloop()
    def next(self):
        for sd in testdata[self.test_data_index]:
            self.canvas.add_srcdst( sd )
        self.test_data_index += 1
        if self.test_data_index>=len(testdata):
            self.test_data_index = 0
        self.canvas.draw()

class SrcDst(object):
    def __init__(self, src, dst):
        self.src=src
        self.dst=dst
    def __repr__(self):
        return '%s->%s' % (self.src, self.dst)

testdata = [[SrcDst('start', 'end')],
            [SrcDst('A','BB'),SrcDst('C', 'BB'),SrcDst('A','AA'), SrcDst('B', 'BB'),SrcDst('D', 'DD')]]

App()
